/*
 * The contents of this file are subject to the Mozilla Public License Version
 * 1.1 (the "License"); you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS" basis,
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 * for the specific language governing rights and limitations under the
 * License.
 *
 * The Original Code is ST_EXT-S_UIMAST.
 *
 * The Initial Developer of the Original Code is
 * University of Rome, Tor Vergata
 * Portions created by the Initial Developer are Copyright (C) 2009
 * the Initial Developer. All Rights Reserved.
 */

package it.uniroma2.art.uimast.impl;

import it.uniroma2.art.ontapi.ARTResource;
import it.uniroma2.art.uimast.impl.types.BooleanVariant;
import it.uniroma2.art.uimast.impl.types.ByteVariant;
import it.uniroma2.art.uimast.impl.types.DoubleVariant;
import it.uniroma2.art.uimast.impl.types.EnumeratedVariant;
import it.uniroma2.art.uimast.impl.types.FloatVariant;
import it.uniroma2.art.uimast.impl.types.IntVariant;
import it.uniroma2.art.uimast.impl.types.LongVariant;
import it.uniroma2.art.uimast.impl.types.ShortVariant;
import it.uniroma2.art.uimast.impl.types.StringVariant;
import it.uniroma2.art.uimast.xpts.IVariantVisitor;
import it.uniroma2.art.uimast.xpts.Variant;

import java.util.Iterator;
import org.apache.uima.cas.*;
import org.w3c.dom.Element;

/**
 * Assigns a value to a feature which has only a value.
 * 
 * @author <a href="mailto:manuel.fiorelli@gmail.com">Manuel Fiorelli</a>
 */
public class SingleValuedFeature extends FeatureProjection {

	/**
	 * Constructs a <code>SingleValuedFeature</code> object.
	 * 
	 * @param classProjection
	 *            the owner class projection
	 * @param feature
	 *            the feature to initialize
	 * @param e
	 *            the DOM element describing the projection
	 * @throws Exception
	 */
	public SingleValuedFeature(ClassProjection classProjection, Feature feature, Element e) throws Exception {
		super(classProjection, feature, DataSource.create(classProjection, classProjection.getCAS().getTypeSystem(),feature.getRange(), e));
	}

	/**
	 * Constructs a <code>SingleValuedFeature</code> object.
	 * 
	 * @param classProjection
	 *            the owner class projection
	 * @param feature
	 *            the feature to initialize
	 * @param mode
	 *            the projection mode: either "value" or "property"
	 * @param value
	 *            the value lexical representation or the property URI
	 * @throws Exception
	 */
	public SingleValuedFeature(ClassProjection classProjection, Feature feature,
			String mode, String value) throws Exception {
		super(classProjection, feature, DataSource.create(classProjection, classProjection.getCAS().getTypeSystem(),
				feature.getRange(), mode, value));
	}

	@Override
	public void apply(ARTResource domainObject, ARTResource annot,
			final FeatureStructure fs) {
		// Gets the source variant.
		Iterator<Variant> it = dataSource.apply(domainObject, annot);

		if (it.hasNext())
			it.next().applyVisitor(new IVariantVisitor() {

				public void visit(BooleanVariant v) {
					fs.setBooleanValue(feature, v.getValue());
				}

				public void visit(ByteVariant v) {
					fs.setByteValue(feature, v.getValue());
				}

				public void visit(ShortVariant v) {
					fs.setShortValue(feature, v.getValue());
				}

				public void visit(IntVariant v) {
					fs.setIntValue(feature, v.getValue());
				}

				public void visit(LongVariant v) {
					fs.setLongValue(feature, v.getValue());
				}

				public void visit(FloatVariant v) {
					fs.setFloatValue(feature, v.getValue());
				}

				public void visit(DoubleVariant v) {
					fs.setDoubleValue(feature, v.getValue());
				}

				public void visit(StringVariant v) {
					fs.setStringValue(feature, v.getValue());
				}

				public void visit(EnumeratedVariant v) {
					fs.setFeatureValueFromString(feature, v.getValue());
				}
			});
	}
}
